#include "LuaState.h"

#include "Global.h"
#include "lua_Input.h"

namespace Lua
{
	LuaState::LuaState()
	{
		L = lua_open();
		if (L == NULL)
		{
			MessageBox(NULL, "Lua state is 'null'", "Lua Error", MB_OK | MB_ICONERROR);
			PostQuitMessage(1);
		}

		luaL_openlibs(L);

		bindFunction(_MessageBox, "MessageBox");
		bindFunction(_PostQuitMessage, "PostQuitMessage");
		bindFunction(_Print, "Print");

		bindInteger(MB_ICONERROR, "MB_ICONERROR");
		bindInteger(MB_ICONINFORMATION, "MB_ICONINFORMATION");

		bindInteger(VERSION_MAJOR, "VERSION_MAJOR");
		bindInteger(VERSION_MINOR, "VERSION_MINOR");
		bindInteger(VERSION_PATCH, "VERSION_PATCH");

		bindLibrary("hook");
		unbindLibrary();

		bindLibrary("input");
		bindMethod(_inputGetMousePos, "GetMousePos");
		bindMethod(_inputIsKeyPress, "IsKeyPress");
		unbindLibrary();

		bindInteger(DIK_ESCAPE, "KEY_ESCAPE");

		luaL_dofile(L, "scripts/lua/includes/base.lua");

		lua_atpanic(L, atPanic);
	}

	void LuaState::update()
	{
		lua_getglobal(L, "hook");
		lua_getfield(L, -1, "Call");
		lua_pushstring(L, "Think");
		lua_call(L, 1,0);
		lua_pop(L, 1);
	}

	void LuaState::bindFunction(LUA_CALLBACK, const char *globalName)
	{
		lua_pushcfunction(L, _cfunction);
		lua_setglobal(L, globalName);
	}

	void LuaState::bindInteger(int _integer, const char *globalName)
	{
		lua_pushinteger(L, _integer);
		lua_setglobal(L, globalName);
	}

	void LuaState::bindLibrary(const char *globalName)
	{
		lua_newtable(L);
		lua_pushvalue(L,-1);
		lua_setglobal(L, globalName);
	}

	void LuaState::bindMethod(LUA_CALLBACK, const char *globalName)
	{
		lua_pushcfunction(L, _cfunction);
		lua_setfield(L, -2, globalName);
	}

	void LuaState::unbindLibrary()
	{
		lua_pop(L,1);
	}

	LUA_FUNCTION(atPanic)
	{
	#ifdef DEBUG_MODE
		std::cout << (char*)lua_tostring(L,-1) << std::endl;
	#else
		MessageBox(NULL, (char*)lua_tostring(_L,-1), "Lua Error", MB_OK | MB_ICONERROR);
	#endif
		return 0;
	}
} // namespace Lua